package com.lxw.oa.controller.common;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lxw.oa.constant.ScheduleConstants;
import com.lxw.oa.controller.BaseController;
import com.lxw.oa.controller.io.BaseTo;
import com.lxw.oa.entity.Menu;
import com.lxw.oa.entity.Role;
import com.lxw.oa.entity.SysUserOnline;
import com.lxw.oa.entity.User;
import com.lxw.oa.enums.OnlineStatus;
import com.lxw.oa.service.BaseService;
import com.lxw.oa.service.MenuService;
import com.lxw.oa.service.RoleService;
import com.lxw.oa.service.SysUserOnlineService;
import com.lxw.oa.shiro.session.OnlineSession;
import com.lxw.oa.shiro.session.OnlineSessionDAO;
import com.lxw.oa.util.*;
import com.lxw.oa.util.scheduleUtil.SpringContextUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.UnknownSessionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.*;

@Controller
@EnableTransactionManagement
@RequestMapping("/system")
public class SystemController{

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private BaseService baseService;

    @Autowired
    private SysUserOnlineService userOnlineService;

    @Autowired
    private OnlineSessionDAO onlineSessionDAO;

    @LogAopIn(moduleName="系统管理-菜单管理",option="页面初始化")
    @GetMapping("/menuManager")
    public String Log_menu()
    {
        return "pages/system/MenuManager";
    }

    @LogAopIn(moduleName="系统管理-角色管理",option="页面初始化")
    @GetMapping("/roleManager")
    public String Log_role()
    {
        return "pages/system/RoleManager";
    }

    @LogAopIn(moduleName="系统管理-账户管理",option="页面初始化")
    @GetMapping("/userManager")
    public String Log_user()
    {
        return "pages/system/UserManager";
    }

    @LogAopIn(moduleName="系统管理-系统日志",option="页面初始化")
    @GetMapping("/systemLog")
    public String Log_systemLog()
    {
        return "pages/system/SystemLog";
    }

    @LogAopIn(moduleName="系统管理-在线管理",option="页面初始化")
    @GetMapping("/userOnline")
    public String Log_userOnline()
    {
        return "pages/system/UserOnline";
    }

    /**
     * 返回该用户的菜单列表
     * @return
     */
    @PostMapping("/getMenuList")
    public String getMenuList(){
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        int  userId = user.getId();
        /** 获取用户角色ID */
        List<Integer> roleIdList = roleService.getUserRoleIds(userId);
        /** 获取角色菜单ID*/
        List<Integer> menuIdList =menuService.getMenuIds(roleIdList);
        /** 获取角色菜单List*/
        List<Menu> menuList =menuService.getMenus(menuIdList);
        return "";
    }

    /**
     * 返回得到所有的一级菜单
     * @return
     */
    @PostMapping("/getTopMenuList")
    @ResponseBody
    public BaseTo getTopMenuList(){
     List<Map<String,String>> list =menuService.getTopMenuList();
        for(Map<String,String> map:list){
            map.put("value",map.get("menu_name"));
        }
        return new BaseTo(list);
    }

    /**
     * 添加一条菜单信息
     * @return
     */
    @LogAopIn(moduleName="系统管理-菜单管理",option="菜单添加")
    @PostMapping("/menuAdd")
    @ResponseBody
    public BaseTo Log_menuAdd(Menu menu){
        menuService.menuAdd(menu);
        return new BaseTo();
    }

    /**
     * 修改一条菜单信息
     * @return
     */
    @LogAopIn(moduleName="系统管理-菜单管理",option="菜单编辑")
    @PostMapping("/menuEdit")
    @ResponseBody
    public BaseTo Log_menuEdit(Menu menu){
        menuService.menuEdit(menu);
        return new BaseTo();
    }

    /**
     * 删除一条菜单信息
     * @return
     */
    @LogAopIn(moduleName="系统管理-系统管理",option="菜单删除")
    @PostMapping("/menuDel")
    @ResponseBody
    public BaseTo Log_menuDel(String  id){
        menuService.menuDel(id);
        return new BaseTo();
    }

    /**
     * 菜单的分页显示
     */
    @RequestMapping("/getPage")
    @ResponseBody
    public Map<String,Object> getPage(BootstrapTable bootstrapTable){
        Map<String,Object>map=new HashMap<String,Object>();
        map.put("rows", baseService.getPage(bootstrapTable));
        map.put("total", baseService.getCnt(bootstrapTable));
        return map;
    }

    /**
     * 菜单的分页显示 得到上部分的列名
     */
    @PostMapping("/getFields")
    @ResponseBody
    public BaseTo getField(String tableName){
        return new BaseTo(baseService.getFields(tableName));
    }


    @LogAopIn(moduleName="全局操作",option="表格导出")
    @GetMapping("/exportMessage")
    public void exportMessage(HttpServletResponse response, String message) {
        message = message.replaceAll("\\(","{");
        message = message.replaceAll("\\)","}");
        JSONObject json = JSONObject.parseObject(message);
        String columnStr=json.getString("columnStr").toString();
        String sort="";
        if(null!=json.getString("sort")){
            sort=json.getString("sort").toString();
        }
        String order="";
        if(null!=json.getString("order")){
            order=json.getString("order").toString();
        }
        String params=json.getString("params").toString();
        Map<String, Object> jsonMap =JSONObject.toJavaObject(JSONObject.parseObject(params), Map.class);
        BootstrapTable bootstrapTable=new BootstrapTable();
        bootstrapTable.setOrder(sort);
        bootstrapTable.setOrder(order);
        bootstrapTable.setParams(jsonMap);
        String [] column=columnStr.split(",");
        List<Map<String,Object>> list=baseService.getExportMessage(bootstrapTable);
        List<Map<String,String>> fileTitle=baseService.getFields(jsonMap.get("tableName").toString());
        String [] columnComStr=new String[column.length];
        for(Map<String,String>map:fileTitle){
            for(int i=0;i<column.length;i++){
                if(column[i].equalsIgnoreCase(map.get("column_name"))){
                    columnComStr[i]=map.get("column_comment");
                    break;
                }
            }
         }
        Workbook hwb=PoiExcelUtil.exportExcelForAll(list,column,columnComStr);
        //response.setHeader("content-type", "application/octet-stream");
        response.setContentType(FileUtil.getReponseType(".xls"));
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(jsonMap.get("tableName").toString()+".xls", "UTF-8"));
            OutputStream os= response.getOutputStream();
            hwb.write(os);
            os.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    /**
     * 所有数据的添加与编辑
     */
    @LogAopIn(moduleName="全局操作",option="添加或编辑操作")
    @PostMapping("/addOrEdt")
    @ResponseBody
    public BaseTo Log_addOrEdt(String message) {
        JSONObject json = JSONObject.parseObject(message);
        JSONArray columnArray=JSONArray.parseArray(json.getString("column"));
        JSONArray valueArray=JSONArray.parseArray(json.getString("value"));
        int columnlength=columnArray.size();
        int valuelength=valueArray.size();
        String [] column=columnArray.toArray(new String[columnlength]);
        String [] value=valueArray.toArray(new String[valuelength]);
        String tableName=json.getString("tableName").toString();
        String saveType=json.getString("saveType").toString();

        if("add".equalsIgnoreCase(saveType)){
            baseService.add(column,value,tableName);
        }else{
            String id=json.getString("id").toString();
            baseService.edt(id,column,value,tableName);

        }
        return new BaseTo();
    }


    /**
     * 所有数据的删除
     */
    @LogAopIn(moduleName="全局操作",option="删除操作")
    @PostMapping("/del")
    @ResponseBody
    public BaseTo Log_del(String tableName,String id) {
        String [] ids=id.split(",");
        for(String idOne:ids){
            baseService.del(idOne,tableName);
        }
        return new BaseTo();
    }

    /**
     * 返回菜单的树形表格图
     */
    @PostMapping("/getTreeGrid")
    @ResponseBody
    public List<MenuTreeGridData> getTreeGrid(String roleId) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        int  userId = user.getId();
        /** 获取用户角色ID */
        List<Integer> roleIdList = new ArrayList<>();
        List<Integer> menuIdList = new ArrayList<>();
        if(roleId==null||"".equals(roleId)){

        }else{
            roleIdList.add(Integer.parseInt(roleId));
            /** 获取角色菜单ID*/
            menuIdList =menuService.getMenuIds(roleIdList);
        }
        /** 获取角色菜单List*/
        List<Menu> menuList =menuService.getMenus(menuIdList);

        Iterator<Menu>it=menuList.iterator();
        while(it.hasNext()){
            if(!it.next().getMenu_level().equals("2")){
                it.remove();
            }
        }
        List<MenuTreeGridData> allData = new ArrayList<>();

        // 加载根菜单
        MenuTreeGridData OARootData = new MenuTreeGridData();
        OARootData.setMenu_name("OA根目录");
        OARootData.setMenu_id("RootOA");
        OARootData.setChildren(new ArrayList<MenuTreeGridData>());
        // 加载OA顶级菜单
        List<Menu> OATopMenus = menuService.getTopMenus();
        for (Menu OATopMenu: OATopMenus) {
            MenuTreeGridData OATopData = new MenuTreeGridData();
            OATopData.setMenu_id(OATopMenu.getId()+"");
            OATopData.setMenu_name(OATopMenu.getMenu_name());
            OATopData.setMenu_selected(false);
            OATopData.setChildren(new ArrayList<MenuTreeGridData>());
            OARootData.getChildren().add(OATopData);
            // 加载OA二级菜单
            List<Menu> OAChildrenMenus = menuService.getMenusByTopId(OATopMenu.getId()+"");
            for (Menu OAChildrenMenu: OAChildrenMenus) {
                MenuTreeGridData OAChildrenData = new MenuTreeGridData();
                OAChildrenData.setMenu_id(OAChildrenMenu.getId()+"");
                OAChildrenData.setMenu_name(OAChildrenMenu.getMenu_name());
                OAChildrenData.setMenu_selected(false);
                OATopData.getChildren().add(OAChildrenData);
                for (Menu roleMenu: menuList) {
                    if ((roleMenu.getId()+"").equals(OAChildrenData.getMenu_id())) {
                        OAChildrenData.setMenu_selected(true);
                    }
                }
            }
        }

        allData.add(OARootData);
        return allData;
    }


    /**
     * 根据前台的数据授权情况改变角色的菜单
     */
    @LogAopIn(moduleName="系统管理-角色管理",option="角色菜单授权")
    @PostMapping("/setRoleMenu")
    @ResponseBody
    public BaseTo Log_setRoleMenu(String roleId,String menuIds) {
        baseService.setRoleMenu(roleId,menuIds);
        return new BaseTo();
    }


    /**
     * 根据前台的数据授权情况改变角色的菜单
     */
    @LogAopIn(moduleName="系统管理-角色管理",option="角色设置")
    @PostMapping("/setUserRole")
    @ResponseBody
    public BaseTo Log_setUserRole(String userId,String roleIds) {
        baseService.setUserRole(userId,roleIds);
        return new BaseTo();
    }



    /**
     * 根据前台的用户角色授权情况显示菜单
     */
    @PostMapping("/getRoleGrid")
    @ResponseBody
    public BaseTo getRoleGrid(String userId){
        List<RoleGridData> RoleGridDataList = new ArrayList<>();
        List<Role> roleList = roleService.getRoles();
        List<Integer> userRoleList=new ArrayList<>();
        if(userId==null||"".equals(userId)){

        }else{
            userRoleList = roleService.getUserRoleIds(Integer.parseInt(userId));
        }
        for (Role role: roleList) {
            RoleGridData roleGridData = new RoleGridData();
            roleGridData.setRole_id(role.getId()+"");
            roleGridData.setRole_name(role.getRole_name());
            roleGridData.setRole_selected(false);
            if(userRoleList!=null&&userRoleList.size()>0){
                for (int  userRoleID: userRoleList) {
                    if (userRoleID==role.getId()) {
                        roleGridData.setRole_selected(true);
                    }
                }
            }
            RoleGridDataList.add(roleGridData);
        }
        return new BaseTo(RoleGridDataList);
    }

    /**
     * 修改密码
     * @return
     */
    @LogAopIn(moduleName="系统管理",option="密码修改")
    @PostMapping("/ChangePwd")
    @ResponseBody
    public BaseTo Log_ChangePwd(String oldPwd, String newPwd1, String newPwd2){
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        if (!(oldPwd.equals(user.password))){
            return new BaseTo("1");
        }
        if (!(newPwd2.equals(newPwd1))){
            return new BaseTo("2");
        }
        if(oldPwd.equals(newPwd1)||oldPwd.equals(newPwd2)){
            return new BaseTo("3");
        }
        Map<String,Object> map = new HashMap<>();
        map.put("id",user.getId());
        map.put("password",newPwd2);
        baseService.edtPwd(map);
        return new BaseTo("4");
    }


    @LogAopIn(moduleName="系统管理-在线管理",option="用户强退")
    @PostMapping("/forceOut")
    @ResponseBody
    public BaseTo Log_forceLogout(String sessionId)
    {
      String message="";
      String[] sessions=sessionId.split(",");
      int count=0;
        for(String sid:sessions){
            if (sid.equals(ShiroUtils.getSessionId()))
            {
                message="flase";
                break;
            }
        }
      if(message.equalsIgnoreCase("flase")){
            return new BaseTo(message);
      }

      for(String sid:sessions){
          SysUserOnline online = userOnlineService.selectOnlineById(sid);
          if (online == null)
          {
              continue;
          }
          if (online.getStatus()==OnlineStatus.off_line)
          {
              continue;
          }
          if (online.getStatus()==OnlineStatus.kick_out)
          {
              continue;
          }
          online.setStatus(OnlineStatus.off_line);
          userOnlineService.saveOnline(online);
          count++;
          OnlineSession onlineSession=null;
          try {
              onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId());
          }catch (UnknownSessionException e){
              continue;
          }
          if (onlineSession == null) {
              continue;
          }
          onlineSession.setStatus(OnlineStatus.off_line);
      }
        message=count+"";
        return  new BaseTo(message);
    }

    /**
     * 获得所有任务信息
     * @return
     */
    @PostMapping("/getScheTasks")
    @ResponseBody
    public BaseTo getScheTasks(){
        String[] AllBeanName=SpringContextUtil.getAllBeanName();
        //存放返回前台的定时任务类数据
        List<Map<String,List<String>>>list=new ArrayList<Map<String,List<String>>>();
        for(String beanName:AllBeanName){
               if(beanName.startsWith(ScheduleConstants.OA_TASK_CLASSNAME)){
                   //存放每个类中的方法类别
                   Map<String,List<String>>map=new HashMap<String,List<String>>();
                   //存放每种方法的方法名
                   List<String>listParam=new ArrayList<String>();
                   List<String>listNoParam=new ArrayList<String>();
                   Method[] methods=SpringContextUtil.getBean(beanName).getClass().getDeclaredMethods();
                   for(Method method:methods){
                       if(method.getName().startsWith(ScheduleConstants.OA_TASK_METHODNAME)){
                           int count=method.getParameterCount();
                           if(count==0){
                               listNoParam.add(method.getName());
                           }else if(count==1){
                               listParam.add(method.getName());
                           }
                       }
                   }
                   List<String>listClassName=new ArrayList<String>();
                   listClassName.add(beanName);
                   map.put("ClassName",listClassName);
                   map.put("NoParams",listNoParam);
                   map.put("Params",listParam);
                   list.add(map);
               }
        }
        return new BaseTo(list);
    }



}
